#pragma once
#include "Socket.hpp"
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/select.h>
#include <sys/time.h>
#include <string>

using std::string;
using std::cout;
using std::cin;
using std::endl;

const int maxnum = 1024;
const int defaultfd = -1;
const int non_event = 0;

int debug_cnt = 0;

class PollServer
{
public:
    PollServer(){}
    PollServer(uint16_t port)
    :_port(port)
    {}
    ~PollServer(){}

    void InitServer()
    {
        _listensock.Socket();
        _listensock.Bind(_port);
        _listensock.Listen();

        for(int i = 0; i < maxnum; i++)
        {
            _events_fd[i].fd = defaultfd;   //初始化fd与事件
            _events_fd[i].events = non_event;
            _events_fd[i].revents = non_event;
        }
    }

    void Accpter()
    {
        //需要先遍历_fd_array找到一个“有效”位置，让accept获取到的fd “被关心”
        int newsock = _listensock.Accpet(nullptr, nullptr);
        if(newsock < 0)
        {
            return;
        }

        int pos = 1;
        for(; pos < maxnum; pos++)
        {
            if(_events_fd[pos].fd != defaultfd)
            {
                continue;
            }
            else
            {
                break;
            }
        }

        if(pos == maxnum)
        {
            cout << "shortage of fd_set" <<endl;
            close(newsock);
            return;
        }

        _events_fd[pos].fd = newsock;
        _events_fd[pos].events = POLLIN;
    }

    void Receiver(int rfd, int pos)
    {
        char buffer[1024] = {0};
        ssize_t n = read(rfd, buffer, sizeof(buffer));      //注意读到的数据不一定完整噢
        if(n < 0)
        {
            cerr << "read error" << endl;
            close(rfd);
            _events_fd[pos].fd = defaultfd;     //表示pos位置可“使用”/“有效”
        }
        else if(n == 0)
        {   
            cout << "disconnect..." << endl;
            close(rfd);
            _events_fd[pos].fd = defaultfd;     //表示pos位置可“使用”/“有效”
        }
        else
        {
            cout << "server says: " << buffer << endl;
        }
    }

    void Dispatcher()
    {
        cout << "this is " << debug_cnt++ << " time to dispatch" << endl;   //for debug

        //还是需要遍历看哪些fd“有效”
        for(int i = 0; i < maxnum; i++)
        {
            pollfd pfd = _events_fd[i];
            if(pfd.fd == defaultfd)
            {
                continue;
            }      

            //进行派发
            if(pfd.revents & POLLIN)    //假设这里只有读事件
            {
                if(pfd.fd == _listensock.GetFd())
                {
                    Accpter();
                }
                else    
                {
                    Receiver(pfd.fd, i);
                }                
            }
            
        }
    }


    void DebugPrint(int n)
    {
        cout << "now we have fds: ";
        for(int i = 0; i < n; i++)
        {
            cout << _events_fd[i].fd << " ";
        }
        cout << endl;
    }

    void Start()
    {
        int listensock = _listensock.GetFd();
        _events_fd[0].fd = listensock;      //整个过程中，第一个就绪的事件一定是连接建立
        _events_fd[0].events = POLLIN;      //注意还要设置关心的事件
        int timeout = 3000;
        while(1)
        {   
            int ret = poll(_events_fd, maxnum, -1);       //相比select这里不需要遍历了，遍历的工作交给了Dispatcher
            if(ret < 0)
            {
                cerr << "poll error" << endl;
            }
            else if(ret == 0)
            {
                cout << "not ready" << endl;
                sleep(1);
            }
            else    //链接建立后才可能分派
            {
                //TODO
                Dispatcher();
            }  
            
        }
    }


private:
    struct pollfd _events_fd[maxnum];      //存放需要关心的pollfd们
    Sock _listensock;
    uint16_t _port;
};